﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ICSharpCode.WinFormsUI.Controls.Chart3D
{
    public class ColumnBar3D : Shape3D
    {
        Point3D[] _vertexes = null; 

        private System.Drawing.SizeF _size;
        public System.Drawing.SizeF Size
        {
            get { return _size; }
            set { _size = value; }
        }

        private Point3D location;
        public Point3D Location
        {
            get { return location; }
            set
            {
                location = value;

                //float _max = Math.Max(Math.Max(_location.X, _location.Y), _location.Z);
                //float _mix = Math.Min(Math.Min(_location.X, _location.Y), _location.Z);

                float _max = Math.Max(location.X, location.Z);
                float _mix = Math.Min(location.X, location.Z);

                //Maxnum(new Point3D[] { new Point3D(_max, _location.Y, _max), new Point3D(_mix, _location.Y, _mix) });
                Maxnum(new Point3D[] { new Point3D(location.X, location.Y, location.Z) });
                _vertexes = new Point3D[8];               

                //_vertexes[0] = new Point3D(_location.X - _size.Width, _location.Y, _location.Z + _size.Width);
                //_vertexes[1] = new Point3D(_location.X + _size.Width, _location.Y, _location.Z + _size.Width);
                //_vertexes[2] = new Point3D(_location.X + _size.Width, 0, _location.Z + _size.Width);
                //_vertexes[3] = new Point3D(_location.X - _size.Width, 0, _location.Z + _size.Width);
                //_vertexes[4] = new Point3D(_location.X - _size.Width, _location.Y, _location.Z - _size.Width);
                //_vertexes[5] = new Point3D(_location.X + _size.Width, _location.Y, _location.Z - _size.Width);
                //_vertexes[6] = new Point3D(_location.X + _size.Width, 0, _location.Z - _size.Width);
                //_vertexes[7] = new Point3D(_location.X - _size.Width, 0, _location.Z - _size.Width);

                _vertexes[0] = new Point3D(location.X - _size.Width + _size.Width, location.Y, location.Z + _size.Width + _size.Width);
                _vertexes[1] = new Point3D(location.X + _size.Width + _size.Width, location.Y, location.Z + _size.Width + _size.Width);
                _vertexes[2] = new Point3D(location.X + _size.Width + _size.Width, 0, location.Z + _size.Width + _size.Width);
                _vertexes[3] = new Point3D(location.X - _size.Width + _size.Width, 0, location.Z + _size.Width + _size.Width);
                _vertexes[4] = new Point3D(location.X - _size.Width + _size.Width, location.Y, location.Z - _size.Width + _size.Width);
                _vertexes[5] = new Point3D(location.X + _size.Width + _size.Width, location.Y, location.Z - _size.Width + _size.Width);
                _vertexes[6] = new Point3D(location.X + _size.Width + _size.Width, 0, location.Z - _size.Width + _size.Width);
                _vertexes[7] = new Point3D(location.X - _size.Width + _size.Width, 0, location.Z - _size.Width + _size.Width);

            }
        }

        private Color fillColor = Color.Transparent;
        public Color FillColor
        {
            get { return fillColor; }
            set { fillColor = value; }
        }

        public ColumnBar3D()
        {
            _size = new System.Drawing.SizeF(8, 8);
            _dashStyleSize = 16;
            _dashStyleIsVisable = true;            
        }

        public ColumnBar3D(System.Windows.Forms.Control control, Camera camera, Coordinate3D coordinate)
            : this()
        {
            this.camera = camera;
            this.control = control;
            this.coordinate = coordinate;
            DoDashStyleChanged();
        }

        public override void Draw(System.Drawing.Graphics g)
        {
            if (_vertexes != null)
            {
                var _SmoothingMode = g.SmoothingMode;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                var pts2d = this.camera.GetProjection(Convert.ToVertexs(this.coordinate, _vertexes));

                PointF[][] face = new PointF[6][];
                face[0] = new PointF[] { pts2d[0].ToPointF(), pts2d[1].ToPointF(), pts2d[2].ToPointF(), pts2d[3].ToPointF() };
                face[1] = new PointF[] { pts2d[5].ToPointF(), pts2d[1].ToPointF(), pts2d[0].ToPointF(), pts2d[4].ToPointF() };
                face[2] = new PointF[] { pts2d[1].ToPointF(), pts2d[5].ToPointF(), pts2d[6].ToPointF(), pts2d[2].ToPointF() };
                face[3] = new PointF[] { pts2d[2].ToPointF(), pts2d[6].ToPointF(), pts2d[7].ToPointF(), pts2d[3].ToPointF() };
                face[4] = new PointF[] { pts2d[3].ToPointF(), pts2d[7].ToPointF(), pts2d[4].ToPointF(), pts2d[0].ToPointF() };
                face[5] = new PointF[] { pts2d[4].ToPointF(), pts2d[7].ToPointF(), pts2d[6].ToPointF(), pts2d[5].ToPointF() };

                if (fillColor != Color.Transparent)
                {
                    using (var brush = new SolidBrush(fillColor))
                    {
                        for (int i = 0; i < 6; i++)
                        {
                            if (Vector2D.IsClockwise(face[i][0], face[i][1], face[i][2]))
                            {
                                g.FillPolygon(brush, face[i]);
                            }
                        }
                    }
                }

                if (lineColor != Color.Transparent)
                {
                    using (var linePen = new Pen(lineColor, lineWidth))
                    {
                        for (int i = 0; i < 6; i++)
                        {
                            if (!Vector2D.IsClockwise(face[i][0], face[i][1], face[i][2]))
                            {
                                g.DrawPolygon(linePen, face[i]);
                            }
                        }
                    }
                }

                g.SmoothingMode = _SmoothingMode;
                
            }   
        }

        public override bool FindNestPoint(Point point, out Point3D result)
        {
            result = null;
            var pts2d = this.camera.GetProjection(Convert.ToVertexs(this.coordinate, _vertexes));
            using (System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath())
            {
                gp.AddPolygon(new PointF[]{
                     pts2d[0].ToPointF(),pts2d[4].ToPointF(),pts2d[5].ToPointF(),
                     pts2d[6].ToPointF(),pts2d[2].ToPointF(),pts2d[3].ToPointF(),pts2d[0].ToPointF() 
                });
                gp.CloseFigure();
                if (gp.IsVisible(point))
                {
                    result = Location;
                    return true;
                }
            }
            return false;
        }

    }
}
